home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 23 / AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso / Tools / Text-Viewer / MSWordView / mswordview_src / utf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-06  |  3.8 KB  |  221 lines

  1. #ifdef PLAN9
  2. #include    <u.h>
  3. #include    <libc.h>
  4. #include    <bio.h>
  5. #else
  6. #include    <sys/types.h>
  7. #include    <stdio.h>
  8. #include    <stdlib.h>
  9. #include    <string.h>
  10. #include    <unistd.h>
  11. #include    <errno.h>
  12. #include    "plan9.h"
  13. #endif
  14. #include    "hdr.h"
  15. #include     "utf.h"
  16. #include     "config.h"
  17. #include     "mswordview.h"
  18.  
  19. enum
  20. {
  21.     Char1    = Runeself,    Rune1    = Runeself,
  22.     Char21    = 0xA1,        Rune21    = 0x0100,
  23.     Char22    = 0xF6,        Rune22    = 0x4016,
  24.     Char3    = 0xFC,        Rune3    = 0x10000,    /* really 0x38E2E */
  25.     Esc    = 0xBE,        Bad    = Runeerror
  26. };
  27.  
  28. #ifdef PLAN9
  29. int    errno;
  30. #endif
  31.  
  32. enum
  33. {
  34.     T1    = 0x00,
  35.     Tx    = 0x80,
  36.     T2    = 0xC0,
  37.     T3    = 0xE0,
  38.     T4    = 0xF0,
  39.     T5    = 0xF8,
  40.     T6    = 0xFC,
  41.  
  42.     Bit1    = 7,
  43.     Bitx    = 6,
  44.     Bit2    = 5,
  45.     Bit3    = 4,
  46.     Bit4    = 3,
  47.     Bit5    = 2,
  48.     Bit6    = 2,
  49.  
  50.     Mask1    = (1<<Bit1)-1,
  51.     Maskx    = (1<<Bitx)-1,
  52.     Mask2    = (1<<Bit2)-1,
  53.     Mask3    = (1<<Bit3)-1,
  54.     Mask4    = (1<<Bit4)-1,
  55.     Mask5    = (1<<Bit5)-1,
  56.     Mask6    = (1<<Bit6)-1,
  57.  
  58.     Wchar1    = (1UL<<Bit1)-1,
  59.     Wchar2    = (1UL<<(Bit2+Bitx))-1,
  60.     Wchar3    = (1UL<<(Bit3+2*Bitx))-1,
  61.     Wchar4    = (1UL<<(Bit4+3*Bitx))-1,
  62.     Wchar5    = (1UL<<(Bit5+4*Bitx))-1
  63.  
  64. #ifndef    EILSEQ
  65.     , /* we hate ansi c's comma rules */
  66.     EILSEQ    = 123
  67. #endif /* PLAN9 */
  68. };
  69.  
  70. int
  71. our_wctomb(char *s, unsigned long wc)
  72. {
  73.     if(s == 0)
  74.         return 0;        /* no shift states */
  75.     if(wc & ~Wchar2) {
  76.         if(wc & ~Wchar4) {
  77.             if(wc & ~Wchar5) {
  78.                 /* 6 bytes */
  79.                 s[0] = T6 | ((wc >> 5*Bitx) & Mask6);
  80.                 s[1] = Tx | ((wc >> 4*Bitx) & Maskx);
  81.                 s[2] = Tx | ((wc >> 3*Bitx) & Maskx);
  82.                 s[3] = Tx | ((wc >> 2*Bitx) & Maskx);
  83.                 s[4] = Tx | ((wc >> 1*Bitx) & Maskx);
  84.                 s[5] = Tx |  (wc & Maskx);
  85.                 return 6;
  86.             }
  87.             /* 5 bytes */
  88.             s[0] = T5 |  (wc >> 4*Bitx);
  89.             s[1] = Tx | ((wc >> 3*Bitx) & Maskx);
  90.             s[2] = Tx | ((wc >> 2*Bitx) & Maskx);
  91.             s[3] = Tx | ((wc >> 1*Bitx) & Maskx);
  92.             s[4] = Tx |  (wc & Maskx);
  93.             return 5;
  94.         }
  95.         if(wc & ~Wchar3) {
  96.             /* 4 bytes */
  97.             s[0] = T4 |  (wc >> 3*Bitx);
  98.             s[1] = Tx | ((wc >> 2*Bitx) & Maskx);
  99.             s[2] = Tx | ((wc >> 1*Bitx) & Maskx);
  100.             s[3] = Tx |  (wc & Maskx);
  101.             return 4;
  102.         }
  103.         /* 3 bytes */
  104.         s[0] = T3 |  (wc >> 2*Bitx);
  105.         s[1] = Tx | ((wc >> 1*Bitx) & Maskx);
  106.         s[2] = Tx |  (wc & Maskx);
  107.         return 3;
  108.     }
  109.     if(wc & ~Wchar1) {
  110.         /* 2 bytes */
  111.         s[0] = T2 | (wc >> 1*Bitx);
  112.         s[1] = Tx | (wc & Maskx);
  113.         return 2;
  114.     }
  115.     /* 1 byte */
  116.     s[0] = T1 | wc;
  117.     return 1;
  118. }
  119.  
  120. int
  121. our_mbtowc(unsigned long *p, char *s, unsigned n)
  122. {
  123.     U8 *us;
  124.     int c0, c1, c2, c3, c4, c5;
  125.     unsigned long wc;
  126.  
  127.     if(s == 0)
  128.         return 0;        /* no shift states */
  129.  
  130.     if(n < 1)
  131.         goto badlen;
  132.     us = (U8*)s;
  133.     c0 = us[0];
  134.     if(c0 >= T3) {
  135.         if(n < 3)
  136.             goto badlen;
  137.         c1 = us[1] ^ Tx;
  138.         c2 = us[2] ^ Tx;
  139.         if((c1|c2) & T2)
  140.             goto bad;
  141.         if(c0 >= T5) {
  142.             if(n < 5)
  143.                 goto badlen;
  144.             c3 = us[3] ^ Tx;
  145.             c4 = us[4] ^ Tx;
  146.             if((c3|c4) & T2)
  147.                 goto bad;
  148.             if(c0 >= T6) {
  149.                 /* 6 bytes */
  150.                 if(n < 6)
  151.                     goto badlen;
  152.                 c5 = us[5] ^ Tx;
  153.                 if(c5 & T2)
  154.                     goto bad;
  155.                 wc = ((((((((((c0 & Mask6) << Bitx) |
  156.                     c1) << Bitx) | c2) << Bitx) |
  157.                     c3) << Bitx) | c4) << Bitx) | c5;
  158.                 if(wc <= Wchar5)
  159.                     goto bad;
  160.                 *p = wc;
  161.                 return 6;
  162.             }
  163.             /* 5 bytes */
  164.             wc = ((((((((c0 & Mask5) << Bitx) |
  165.                 c1) << Bitx) | c2) << Bitx) |
  166.                 c3) << Bitx) | c4;
  167.             if(wc <= Wchar4)
  168.                 goto bad;
  169.             *p = wc;
  170.             return 5;
  171.         }
  172.         if(c0 >= T4) {
  173.             /* 4 bytes */
  174.             if(n < 4)
  175.                 goto badlen;
  176.             c3 = us[3] ^ Tx;
  177.             if(c3 & T2)
  178.                 goto bad;
  179.             wc = ((((((c0 & Mask4) << Bitx) |
  180.                 c1) << Bitx) | c2) << Bitx) |
  181.                 c3;
  182.             if(wc <= Wchar3)
  183.                 goto bad;
  184.             *p = wc;
  185.             return 4;
  186.         }
  187.         /* 3 bytes */
  188.         wc = ((((c0 & Mask3) << Bitx) |
  189.             c1) << Bitx) | c2;
  190.         if(wc <= Wchar2)
  191.             goto bad;
  192.         *p = wc;
  193.         return 3;
  194.     }
  195.     if(c0 >= T2) {
  196.         /* 2 bytes */
  197.         if(n < 2)
  198.             goto badlen;
  199.         c1 = us[1] ^ Tx;
  200.         if(c1 & T2)
  201.             goto bad;
  202.         wc = ((c0 & Mask2) << Bitx) |
  203.             c1;
  204.         if(wc <= Wchar1)
  205.             goto bad;
  206.         *p = wc;
  207.         return 2;
  208.     }
  209.     /* 1 byte */
  210.     if(c0 >= Tx)
  211.         goto bad;
  212.     *p = c0;
  213.     return 1;
  214.  
  215. bad:
  216.     errno = EILSEQ;
  217.     return -1;
  218. badlen:
  219.     return -2;
  220. }
  221.